#pragma once
#include "httpclient.h"
#include "DockerElement.h"

namespace NSDockerClient {

typedef std::unordered_map<std::string, std::string> TDDockerQueryFilters;

class DockerClient
{
public:
    DockerClient(const char *IP, unsigned short port);
    ~DockerClient();
public:
    /*** Image ***/
    void ListImages(bool bAll, bool bDigests, const TDDockerQueryFilters *filters, std::function<void(bool, std::vector<SDockerImage>&, std::string &ErrorString)> funNotify);
    void ImportImage(input_stream &tarball, std::function<void(bool, std::string &Repository, std::string &Tag, std::string &ErrorString)> funNotify, bool bQuiet = true);
    void ExportImage(const std::string &ID, std::function<void(bool, void *tarball, size_t tb_size, std::string &ErrorString)> funNotify);
    void RemoveImage(const std::string &ID, std::function<void(bool, std::string &ErrorString)> funNotify, bool bForce = false, bool bNoPrune = false);
    /*** Container ***/
    void ListContainers(bool bAll, int limit, bool bGetSize, const TDDockerQueryFilters *filters, std::function<void(bool, std::vector<SDockerContainer>&, std::string &ErrorString)> funNotify);
    void InspectContainer(const std::string &ID, bool bGetSize, std::function<void(bool, SDockerContainer&, std::string &ErrorString)> funNotify);
    void CreateContainer(const SDockerContainerCreation &Creation, std::function<void(bool, SDockerContainerCreationResult&, std::string &ErrorString)> funNotify);
    void RemoveContainer(const std::string &ID, const SDockerContainerRemove &Rv, std::function<void(bool, std::string &ErrorString)> funNotify);
    void StartContainer(const std::string &ID, std::function<void(bool, std::string &ErrorString)> funNotify);
    void StopContainer(const std::string &ID, std::function<void(bool, std::string &ErrorString)> funNotify);
    void RestartContainer(const std::string &ID, std::function<void(bool, std::string &ErrorString)> funNotify);
    void KillContainer(const std::string &ID, const std::string &Signal, std::function<void(bool, std::string &ErrorString)> funNotify); //e.g. Signal: SIGKILL(default)/SIGINT
    void ProcessStatusInsideContainer(const std::string &ID, std::string PSArgs, std::function<void(bool, SDockerContainerProcessStatus&, std::string &ErrorString)> funNotify);
    /*** NetWork ***/
    void ListNetWorks(const TDDockerQueryFilters *filters, std::function<void(bool, std::vector<SDockerNetWork>&, std::string &ErrorString)> funNotify);
    /*** Volume ***/
    void ListVolumes(const TDDockerQueryFilters *filters, std::function<void(bool, std::vector<SDockerVolume>&, std::string &ErrorString)> funNotify);
    void CreateVolume(const SDockerVolumeCreation &Creation, std::function<void(bool, SDockerVolumeCreationResult&, std::string &ErrorString)> funNotify);
    void RemoveVolume(const std::string &ID, bool bForce, std::function<void(bool, std::string &ErrorString)> funNotify);
private:
    NSDockerClient::httpclient m_httpclient;
};

}